package util;

import bean.ConflictWorker;
import bean.Task;
import bean.TaskTeam;
import bean.Worker;

import java.util.ArrayList;

public class DivideConquer2Util {
    GreedyUtil gUtil = new GreedyUtil();

    public void formTeamAgain(ArrayList<TaskTeam> taskTeams, ArrayList<TaskTeam> taskTeamsY, ArrayList<TaskTeam> taskTeamsN, ArrayList<Worker> Wp) {

        //为taskTeams中的任务继续再次匹配
        //先更新tjWorkers
        for (TaskTeam tt : taskTeams) {
            //先更新tjWorkers
            tt.setValidWorkers(gUtil.getTjWorkers(tt.getTask(),Wp));
            //再形成团队

        }

    }


    /**
     * 为冲突的工人conflictWorkers选择最佳的任务，并确认
     * @param conflictWorkers
     * @param taskTeams
     * @param taskTeamsY
     * @param taskTeamsN
     * @param Wp
     */
    public void selectBetterTaskForWorker(ArrayList<ConflictWorker> conflictWorkers, ArrayList<TaskTeam> taskTeams, ArrayList<TaskTeam> taskTeamsY, ArrayList<TaskTeam> taskTeamsN, ArrayList<Worker> Wp) {

        for (ConflictWorker cw : conflictWorkers) {
            TaskTeam bestTaskTeam = new TaskTeam();
            double bestValue = 99999999999999.0;

            for (TaskTeam tt : cw.getTaskTeams()) {
                //先把当前工人从TaskTeam的team中删除
                tt.getTeam().remove(cw.getConflictWorker());
                //找出当前工人的最佳任务
                double nowValue = gUtil.distance(tt.getTask(), cw.getConflictWorker()) / gUtil.maxItem2(tt.getTeam(), cw.getConflictWorker(), tt.getTask().getSkills());
                if (nowValue < bestValue) {
                    bestValue = nowValue;
                    bestTaskTeam = tt;
                }
            }
            //确认此最佳任务
            bestTaskTeam.getTeam().add(cw.getConflictWorker());
            taskTeamsY.add(bestTaskTeam);
            taskTeams.remove(bestTaskTeam);
            for (Worker bw : bestTaskTeam.getTeam()) {
                Wp.remove(bw);
            }

        }
    }

    /**
     * 确认不冲突的工人和任务
     * @param Wp
     * @param conflictWorkers
     * @param taskTeams
     * @return
     */
    public ArrayList<TaskTeam> confirmWorker(ArrayList<Worker> Wp, ArrayList<ConflictWorker> conflictWorkers, ArrayList<TaskTeam> taskTeams) {
        ArrayList<TaskTeam> taskTeamsY = new ArrayList<>();
        ArrayList<TaskTeam> conflictTaskTeams = new ArrayList<>();
        for (ConflictWorker cw : conflictWorkers) {
            for (TaskTeam tt : cw.getTaskTeams()) {
                conflictTaskTeams.add(tt);
            }
        }

        ArrayList<TaskTeam> notConflictTaskTeams = new ArrayList<>();

        for (TaskTeam tt : taskTeams) {
            boolean conflict = false; //false此任务不冲突的
            for (TaskTeam tt2 : conflictTaskTeams) {
                if (tt.equals(tt2)) {
                    conflict = true;
                }
            }
            if (!conflict) {
                notConflictTaskTeams.add(tt);
            }
        }

        for (TaskTeam tt : taskTeams) {
            for (TaskTeam tt2 : notConflictTaskTeams) {
                if (tt.equals(tt2)) {
                    taskTeamsY.add(tt);
                }
            }
        }

        for (TaskTeam tt : taskTeamsY) {
            for (Worker w : tt.getTeam()) {
                Wp.remove(w);
            }
        }

        for (TaskTeam tty : taskTeamsY) {
            taskTeams.remove(tty);
        }

        return taskTeamsY;
    }

    /**
     * 从最佳选择中找到有冲突的工人
     * @param taskTeams
     * @return
     */
    public ArrayList<ConflictWorker> findConflictWorkers(ArrayList<TaskTeam> taskTeams) {

        ArrayList<ConflictWorker> conflictWorkers = new ArrayList<>();

        for (TaskTeam tt1 : taskTeams) {
            for (Worker w1 : tt1.getTeam()) {

                ArrayList<TaskTeam> conflictTaskTeams = new ArrayList<>();

                for (TaskTeam tt2 : taskTeams) {
                    if (tt1.equals(tt2)) {
                        continue;
                    }
                    for (Worker w2 : tt2.getTeam()) {
                        if (w1.getId() == w2.getId()) {
                            conflictTaskTeams.add(tt2);
                        }
                    }
                }

                if (conflictTaskTeams.size() != 0) {
                    conflictTaskTeams.add(tt1);
                    ConflictWorker cWorker = new ConflictWorker();
                    cWorker.setConflictWorker(w1);
                    cWorker.setTaskTeams(conflictTaskTeams);
                    conflictWorkers.add(cWorker);
                }

            }
        }

        ArrayList<ConflictWorker> reWorkers = new ArrayList<>();

        for (int i = 0; i < conflictWorkers.size(); i++) {
            ConflictWorker cw1 = conflictWorkers.get(i);

            for (int j = i + 1; j < conflictWorkers.size(); j++) {
                ConflictWorker cw2 = conflictWorkers.get(j);
                if (cw1.getConflictWorker().equals(cw2.getConflictWorker())) {
                    reWorkers.add(cw2);
                }
            }
        }

        for (ConflictWorker cw : reWorkers) {
            conflictWorkers.remove(cw);
        }

        return conflictWorkers;
    }


    /**
     * 为一个任务组成团队，
     * Attention！此团队不一定可以满足任务的技能要求，有效工人全部遍历完就结束组队
     * @param tjWorkers 任务tj的有效工人
     * @param tj 当前任务
     * @return taskTeam：任务及对应的团队
     */
    public TaskTeam formTeam(ArrayList<Worker> tjWorkers, Task tj) {
        TaskTeam taskTeam = new TaskTeam();

        //先形成团队，能招几个人算几个人，当工人们tjWorkers全部遍历完，或者工人能够完成任务时break
        // 最后在外部判断此团队是否可以满足任务要求
        //在argMax保证了熵值不为0
        ArrayList<Worker> tjTeam = new ArrayList<>();
        for (Worker tjW : tjWorkers) {
            if (gUtil.isSkillsSatisfy(tj.getSkills(),tjTeam)) {
                break;
            }
            Worker maxWorker = argMax(tjWorkers,tj,tjTeam);
            if (maxWorker.getId() != 0.0) {
                tjTeam.add(maxWorker);
            }
        }

        //此出判断团队是否可以完成任务
        boolean satisfy = gUtil.isSkillsSatisfy(tj.getSkills(), tjTeam);
        if (satisfy) {
            taskTeam.setTask(tj);
            taskTeam.setTeam(tjTeam);
            taskTeam.setValidWorkers(tjWorkers);
            taskTeam.setCompleted(true);
        }else {
            taskTeam.setTask(tj);
            taskTeam.setTeam(tjTeam);
            taskTeam.setValidWorkers(tjWorkers);
            taskTeam.setCompleted(false);
        }

        return taskTeam;
    }

    /**
     * 第一轮，为当前任务tj找出性价比最高的工人
     * 保证了团队熵值不为0
     * @param tjWorkers 任务tj的有效工人
     * @param tj 任务tj
     * @param tjTeam 任务tj的团队
     * @return 性价比最高的工人
     */
    public Worker argMax(ArrayList<Worker> tjWorkers, Task tj, ArrayList<Worker> tjTeam) {
        double argMax = 0;
        Worker maxWorker = new Worker();
        for (Worker worker : tjWorkers) {
            //在这里保证了熵值不为0
            if (tjTeam.size() != 0) {
                if (tjTeam.get(0).getCluster() == worker.getCluster()) {
                    continue;
                }
            }
            int maxItem1 = gUtil.maxItem1(tjTeam,tj.getSkills());
            int maxItem2 = gUtil.maxItem2(tjTeam,worker,tj.getSkills());
            double value = (maxItem2 - maxItem1) / gUtil.distance(tj,worker);
            if ( value>argMax ) {
                argMax = value;
                maxWorker = worker;
            }
        }
        return maxWorker;
    }



}
